﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;

namespace LightCAD.UI
{
    [DefaultEvent("Click")]
    public partial class RibbonButton : UserControl, ITabButton
    {


        private const int DefaultWidth = 72;
        private const int SizeH = 64;
        private const int SmallSizeH = 32;
        private const int ArrowSize = 16;

        private TabButton button;

        public event EventHandler DropDownItemClick;
        private ThemeBase theme;

        private SolidBrush backBrush;
        private SolidBrush textBrush;
        private SolidBrush mouseOverBrush;
        public RibbonButton()
        {
            InitializeComponent();
            this.Width = DefaultWidth;
            this.SizeChanged += RibbonButton_SizeChanged;
            this.MouseDown += this.RibbonButton_MouseDown;
            this.MouseEnter += this.RibbonButton_MouseEnter;
            this.MouseLeave += this.RibbonButton_MouseLeave;
            this.MouseHover += this.RibbonButton_MouseHover;
            this.MouseMove += this.RibbonButton_MouseMove;
            this.MouseUp += this.RibbonButton_MouseUp;

            this.Load += RibbonButton_Load;
            this.Disposed += RibbonButton_Disposed;
        }

        private void RibbonButton_Load(object sender, EventArgs e)
        {
            //this.theme = TabMenuManager.GetTheme?.Invoke();
            //if (this.theme.ColorPalette == null)
            //{
            this.backBrush = (SolidBrush)Brushes.WhiteSmoke;
            this.textBrush = (SolidBrush)Brushes.Black;
            this.mouseOverBrush = (SolidBrush)Brushes.Silver;

            //}
            //else
            //{
            //    this.backBrush = new SolidBrush(this.theme.ColorPalette.TabSelectedInactive.Background);
            //    this.textBrush = new SolidBrush(this.theme.ColorPalette.TabSelectedInactive.Text);
            //    this.mouseOverBrush = new SolidBrush(this.theme.ColorPalette.TabSelectedActive.Background);
            //}
        }

        private void RibbonButton_Disposed(object sender, EventArgs e)
        {
            //this.backBrush.Dispose();
            //this.textBrush.Dispose();
            //this.mouseOverBrush.Dispose();
        }

        private void RibbonButton_SizeChanged(object sender, EventArgs e)
        {
            this.Height = (this.IsSmallSize) ? SmallSizeH : SizeH;
        }

        [Browsable(false)]
        public bool IsSmallSize
        {
            get { return this.button == null ? false : this.button.IsSmallSize; }
        }
        public TabButton Button
        {
            get { return this.button; }
            set
            {
                this.button = value;
                this.Height = (this.IsSmallSize) ? SmallSizeH : SizeH;
                this.Invalidate();
            }
        }

        [Browsable(false)]
        public bool HasDropDown
        {
            get { return this.button == null ? false : this.button.DropDowns.Count > 0; }
        }
        private bool isMouseEnter;
        private void RibbonButton_MouseEnter(object sender, EventArgs e)
        {
            isMouseEnter = true;
            this.Invalidate();
        }

        private void RibbonButton_MouseLeave(object sender, EventArgs e)
        {
            isMouseEnter = false;
            this.Invalidate();
        }
        private Point mouseXY;
        private void RibbonButton_MouseMove(object sender, MouseEventArgs e)
        {
            var pre = mouseXY;
            mouseXY = e.Location;
            if ((pre.X < this.Width - ArrowSize && mouseXY.X >= this.Width - ArrowSize)
                || (pre.X >= this.Width - ArrowSize && mouseXY.X < this.Width - ArrowSize))
            {
                this.Invalidate();
            }
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            var g = e.Graphics;
            if (this.button == null)
            {
                base.OnPaint(e);
                return;
            }
            StringFormat sf= new StringFormat
            {
                LineAlignment = StringAlignment.Center,
                Alignment = StringAlignment.Center
            };
            if (this.HasDropDown)
            {
                var penLeft = isMouseEnter && mouseXY.X < Width - ArrowSize ? mouseOverBrush : backBrush;
                g.FillRectangle(penLeft, new RectangleF(0, 0, Width - ArrowSize, Height));
                var penRight = isMouseEnter && mouseXY.X >= Width - ArrowSize ? mouseOverBrush : backBrush;
                g.FillRectangle(penRight, new RectangleF(Width - ArrowSize, 0, ArrowSize, Height));
                var aps = new PointF[3];
                aps[0] = new PointF(Width - ArrowSize / 3 * 2, Height / 2 - ArrowSize / 6);
                aps[1] = new PointF(Width - ArrowSize / 3, Height / 2 - ArrowSize / 6);
                aps[2] = new PointF(Width - ArrowSize / 2, Height / 2 + ArrowSize / 8);
                g.FillPolygon(textBrush, aps.ToArray());


                RectangleF icoRect, txtRect;
                if (this.IsSmallSize)
                {
                    icoRect = new RectangleF(0, 0, 32, 32);
                    txtRect = new RectangleF(36, 0, Width - 36-ArrowSize, 32);
                    sf.Alignment = StringAlignment.Near;
                }
                else
                {
                    icoRect = new RectangleF((Width - 40 - ArrowSize) / 2, 0, 40, 40);
                    txtRect = new RectangleF(0, 40, Width - ArrowSize, Height-40);
                }
                if (this.button.Icon != null)
                {
                    g.DrawImage(this.button.Icon, icoRect);
                }
                g.DrawString(this.button.Text, this.Font, textBrush, txtRect, sf);
                    
            }
            else
            {
                var pen = isMouseEnter ? mouseOverBrush : backBrush;
                g.FillRectangle(pen, new RectangleF(0, 0, Width, Height));
                RectangleF icoRect, txtRect;
                if (this.IsSmallSize)
                {
                     icoRect = new RectangleF(0, 0, 32, 32);
                     txtRect = new RectangleF(36, 0, Width-36, 32);
                    sf.Alignment = StringAlignment.Near;
                }
                else
                {
                     icoRect = new RectangleF((Width - 40) / 2, 0, 40, 40);
                     txtRect = new RectangleF(0, 40, Width, 24);
                }

                if (this.button.Icon != null)
                {
                    g.DrawImage(this.button.Icon, icoRect);
                }
                g.DrawString(this.button.Text, this.Font, textBrush, txtRect,sf  );

            }
        }

        private void RibbonButton_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.HasDropDown && mouseXY.X >= Width - ArrowSize)
            {
                ContextMenuStrip?.Show(this, new Point(0, Height), ToolStripDropDownDirection.BelowRight);
            }
        }

        protected override void OnClick(EventArgs e)
        {
            if (!this.HasDropDown || (this.HasDropDown && mouseXY.X < Width - ArrowSize))
            {
                base.OnClick(e);
            }
        }
        protected override void OnMouseClick(MouseEventArgs e)
        {
            if (!this.HasDropDown || (this.HasDropDown && mouseXY.X < Width - ArrowSize))
            {
                base.OnMouseClick(e);
            }
        }


        private void RibbonButton_MouseUp(object sender, MouseEventArgs e)
        {

        }

        private void RibbonButton_MouseHover(object sender, EventArgs e)
        {

        }

        public void Remove()
        {
            this.SizeChanged -= RibbonButton_SizeChanged;
            this.MouseDown -= this.RibbonButton_MouseDown;
            this.MouseEnter -= this.RibbonButton_MouseEnter;
            this.MouseLeave -= this.RibbonButton_MouseLeave;
            this.MouseHover -= this.RibbonButton_MouseHover;
            this.MouseMove -= this.RibbonButton_MouseMove;
            this.MouseUp -= this.RibbonButton_MouseUp;
        }

        public void ResetButton(TabButton button)
        {
            this.Button = button;

            if (this.HasDropDown)
            {
                this.CreateDropDown();
            }
        }

        private void CreateDropDown()
        {
            var ctxMenu = new ContextMenuStrip();
            this.ContextMenuStrip = ctxMenu;
            foreach (var btn in this.button.DropDowns)
            {
                if(btn.Name== "__Separator")
                {
                    var menuItem = new ToolStripSeparator();
                    ctxMenu.Items.Add(menuItem);
                }
                else
                {
                    var menuItem = new ToolStripMenuItem { Text = btn.Text };
                    menuItem.Name = btn.Name;
                    menuItem.Image = btn.Icon;
                    menuItem.Tag = btn;
                    ctxMenu.Items.Add(menuItem);
                }
            }
            ctxMenu.ItemClicked += CtxMenu_ItemClicked;
        }

        private void CtxMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            DropDownItemClick?.Invoke(e.ClickedItem, EventArgs.Empty);
        }
    }
}
